package metro.jme.lottery.business;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import me.regexp.RE;
import metro.jme.lottery.util.Converter;
import metro.jme.lottery.util.StringUtil;

/**
 * This class is used to read and parse data from XML/HTML document.
 * It handles everything related to the parsing of the page.
 * @author pierre
 */
public class XmlLoader {

	public static final String URL = "http://www.yle.fi/tekstitv/txt/P471_01.html";  

	/**
	 * Return the webpage located at url
	 * @return 
	 */
	public static String grabPage() {
		InputStream is = null;
		HttpConnection con = null;
		String page = null;

		try {
			con = (HttpConnection) Connector.open(URL, Connector.READ);
			is = con.openInputStream();
			InputStreamReader isr = new InputStreamReader(is, "iso-8859-1");
			page = "";
			char c;
			int car;
			boolean shouldContinue = true;
			while (shouldContinue) {
				car = isr.read();
				if (car == -1) {
					shouldContinue = false;
				} else {
					c = (char) car;
					page += c;
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			return null;
		} finally {
			try {
				if (is != null) {
					is.close();
				}
				if (con != null) {
					con.close();
				}
			} catch (IOException e) {
				System.err.println(e);
			}
		}
		return page;
	}

	/**
	 * Parse the HTML page and return the string containing correct numbers
	 * @param page
	 * @return 
	 */
	private static String findGood(String page) {
		String good = null;
		// Have fun with regex :
		RE re4 = new RE(">\\s*((?:\\d{1,2})(?:,\\d{1,2}){5,})\\s*<");

		if (re4.match(page)) {
			// Parse content :
			good = re4.getParen(1);
		}
		return good;
	}

	/**
	 * Parse the HTML page and return the string containing correct extra numbers
	 * @param page
	 * @return 
	 */
	private static String findBonus(String page) {
		String bonus = null;
		// Have fun with regex :
		RE re4 = new RE(">\\s*((\\d{1,2})(,\\d{1,2}){1,2})\\s*<");

		if (re4.match(page)) {
			// Parse content :
			bonus = re4.getParen(1);
		}
		return bonus;
	}

	/**
	 * Return the list of correct numbers from the HTML page
	 * @param page
	 * @return 
	 */
	public static int[] getGood(String page) throws Exception {
		// Then give it to the magic func, and store results
		String result = findGood(page);

		return (result != null ? StringUtil.splitToInt(result, ",") : null);
	}

	/**
	 * Return the list of extra numbers from the HTML page
	 * @param page
	 * @return 
	 */
	public static int[] getBonus(String page) throws Exception {
		String result = findBonus(page);
		return (result != null ? StringUtil.splitToInt(result, ",") : null);
	}

	/**
	 * This method get the HTML page as parameter and will return a hastable where
	 * each key is something like "4" or "4+1", representing the number of 
	 * correct numbers, and each value is the amount of euros won.
	 * //FIXME: Should split this method into many others, cause it really looks
	 * like shit ...
	 * @param page
	 * @return 
	 */
	public static Hashtable getGains(String page) {
		// Have fun with regex :
		RE re4 = new RE("(.*,\\d\\d)");
		Vector v = new Vector();
		String el;
		int end;

		if (re4.match(page)) {
			end = re4.getParenEnd(1);
			if (end < page.length()) {
				while (re4.match(page, end)) {
					end = re4.getParenEnd(1);
					int n = re4.getParenCount();
					// Check number of capture, 2 means 1 capture, 0 is the match, 1 is the capture
					if (n == 2) {
						el = re4.getParen(1);
						if (el.length() < 50) {
							RE re42 = new RE("[<>]");
							if (!re42.match(el)) {
								v.addElement(el);
							}
						}
					}
				}
			}
		}

		// Clean datas 
		Hashtable gainTable = new Hashtable();
		String key = "";
		String value = "";
		RE re_clean = new RE("(\\d\\+?(?:\\d|\\w)?)[^\\d]*(\\d+(?:\\s\\d+)*,\\d*)\\s*$");

		for (int i = 0; i < v.size(); i++) {
			if (re_clean.match((String) v.elementAt(i))) {
				// We have a gain :
				// ...
				key = re_clean.getParen(1);
				// Sometimes those dummies wrote l instead of 1 so convert it
				key = Converter.dummyConverter(key);
				// ...
				value = re_clean.getParen(2);
				// replace ',' by '.'
				value = StringUtil.getParsable(value);

				gainTable.put(key, value);
			} else {
				// Maybe no match cause no winner
				RE re_no_winner = new RE("(\\d).*e");
				if (re_no_winner.match((String) v.elementAt(i))) {
					// No gains for the given numbers :
					// ...
					key = re_no_winner.getParen(1);
					value = "";
					gainTable.put(key, value);
				}
			}
		}
		return gainTable;
	}
}
